import 'dart:math';
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class CirclePercent extends StatefulWidget {
  final double percent;
  final double width;
  final double lineWidth;
  final Widget child;
  final Color bgColor;
  final Color foreColor;

  CirclePercent({
    @required this.percent,
    this.width = 200.0,
    this.lineWidth = 8.0,
    this.child,
    this.bgColor = Colors.lightBlueAccent,
    this.foreColor = Colors.blueAccent
  });

  @override
  _CirclePercentState createState() => _CirclePercentState();
}

class _CirclePercentState extends State<CirclePercent> with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
  AnimationController percentCtrl;
  Animation<double> percentAnimation;
  double curPercent = 0.0;

  @override
  void initState() {
    _initController();
    _initAnimation();
    super.initState();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    percentCtrl?.dispose();
    super.dispose();
  }

  @override
  bool get wantKeepAlive => false;

  void _initController() {
    percentCtrl = AnimationController(
      duration: Duration(milliseconds: 500),
      vsync: this
    );
  }

  void _initAnimation() {
    percentAnimation = Tween<double>(
      begin: 0.0,
      end: widget.percent
    ).animate(
      CurvedAnimation(
        parent: percentCtrl,
        curve: Interval(0.0, 1.0, curve: Curves.ease)
      )
    )..addListener(() {
      setState(() {
        curPercent = percentAnimation.value;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    percentCtrl.forward();
    return Container(
      width: widget.width,
      height: widget.width,
      padding: EdgeInsets.all(widget.lineWidth / 2),
      child: CustomPaint(
        foregroundPainter: MyPainter(
          bgColor: widget.bgColor,
          foreColor: widget.foreColor,
          percent: widget.percent,
          width: widget.lineWidth
        ), 
        child: Container(
          alignment: Alignment.center,
          child: widget.child, 
        ),
      ),
    );
  }
}

class MyPainter extends CustomPainter {

  Color bgColor;
  Color foreColor;
  double percent;
  double width;

  MyPainter({
    this.bgColor,
    this.foreColor,
    this.percent,
    this.width
  });

  num degToRad(num deg) => deg * (pi / 180.0);

  num radToDeg(num rad) => rad * (180.0 / pi);

  @override
  void paint(Canvas canvas, Size size) {
    Paint line = Paint()
      ..color=bgColor..strokeCap=StrokeCap.round
      ..style=PaintingStyle.stroke..strokeWidth=width;

    Paint complete = Paint()
      ..color=foreColor..strokeCap=StrokeCap.round
      ..style=PaintingStyle.stroke..strokeWidth=width;  

    Offset center = Offset(size.width/2, size.height/2);
    double radius = min(size.width/2, size.height/2); 
    canvas.drawCircle(center, radius, line);   

    double arcAngle = 2*pi*(percent / 100);  

    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      -pi/2,
      arcAngle,
      false,
      complete
    );   
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}